home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The PC-SIG Library 9
/
The PC-SIG Library on CD ROM - Ninth Edition.iso
/
1501_600
/
DISK1533
/
DISK1533.ZIP
/
TAIL.C
< prev
next >
Wrap
Text File
|
1989-02-22
|
4KB
|
174 lines
#include <stdio.h>
#include <local.h>
#define LINSIZ 128 /* max bytes in 1 line */
#define DEFAULT 10 /* default lines used */
#define max(x, y) ((x) > (y) ? (x) : (y))
/*
* TAIL.C - the tail of a file, works like a filter if there are no
* files specified on the command line, the unix utility does not
* allow wildcards in the tail and tail commands, so they are not
* supported, usage like: tail {/n} {file file ... }
*/
static char *Program [] = { "S. Leoce, *nix(tm) tail.c"
"v1.0 r1.0 svclvl 1 va@psj" };
static char *Usage = "usage: tail [/hn#] [file file ...]";
#include "b:cmdline.c"
typedef struct qnode { /* queue entry node */
char *ln; /* next line data area */
struct qnode *next; /* next node in queue */
} node;
static long qsize = 0L;
int main (argc, argv)
char *argv[];
int argc;
{
short unsigned LineOption = FALSE;
short unsigned header = FALSE;
long register number = DEFAULT; /* default lines to write */
FILE *fp; /* file stream pointer */
char line [LINSIZ]; /* input line */
node *enqueue(); /* insert routine */
node *release(); /* the free routine */
node *front = NULL;
node *rear = NULL;
opterr = FALSE;
while ((LineOption = getopt(argc, argv, "hn:")) != EOF)
switch(LineOption) {
case '?':
fprintf(stderr,"tail: illegal option %c\n",badopt);
_exit (0x04);
case 'n':
number = max(atol(optarg),0);
break;
case 'h':
header = TRUE;
} /* switch closed here */
if (number == 0)
_exit(fprintf(stderr,"%s\n", Usage) + 0x04);
if (argv[optind] == NULL) { /* use like a filter now */
while(fgets(line,LINSIZ,stdin) != NULL)
if (number > 0) {
front = enqueue(front,number--,line);
if (++qsize == 1)
rear = front;
else
rear = rear -> next;
}
if (number == 0)
rear -> next = front;
else { /* move the queue down */
rear = front;
front = front -> next;
strcpy(rear -> ln, line);
}
dequeue(front,qsize);
}
else { /* do each file */
long save = number;
while (argv[optind] != NULL) {
if (header)
printf("--------------- %s\n",argv[optind]);
number = save;
qsize = 0L;
if ((fp = fopen(argv[optind++], "r")) == NULL)
_exit(perror(strcat("tail: can't open ",
strupr(argv[optind-1]))) + 0x10);
while(fgets(line, LINSIZ, fp) != NULL)
if (number > 0) { /* enqueue next */
front = enqueue(front,number--,line);
if (++qsize == 1) /* rear is same */
rear = front;
else
rear = rear -> next;
if (number == 0)
rear -> next = front;
}
else { /* move the queue down */
strcpy (front -> ln, line);
rear = front;
front = front -> next;
}
dequeue(front,qsize);
fclose (fp);
front = rear = release(front,qsize);
printf("\n"); /* ensure the newline for next file */
}
} /* else is closed */
return (0);
}
node *enqueue(p,n,data)
node *p;
char *data;
long n;
{
char *strwrt();
if (p == NULL) { /* here's the place to link ... */
if ((p = (node *) malloc(sizeof(node))) == NULL)
_exit(fprintf(stderr,
"tail: insufficient core\n") + 0x10);
p -> ln = strwrt(data, LINSIZ);
p -> next = NULL;
}
else
p -> next = enqueue(p -> next, n, data);
return (p); /* return the pointer here */
}
char *strwrt(s,n) /* save a string s somewhere in memory */
char *s;
unsigned n;
{
char *p;
if ((p = (char *) malloc(n+1)) != NULL)
strcpy (p, s);
else
_exit(fprintf(stderr,"tail: insufficient core\n") + 0x10);
return (p);
}
dequeue(q,n)
node *q;
long n;
{
while (n-- > 0 && q != NULL) {
printf ("%s", q -> ln);
q = q -> next;
}
}
node *release(p,s)
node *p;
long s;
{
/* release the pointers and the node item for next time */
auto node *q = p;
while (s-- > 0) {
q = p -> next;
free (p -> ln);
free (p);
p = q;
}
return (NULL);
}